package com.cloud.class04.controller;

import com.cloud.class04.apis.PayFeignApi;
import io.github.resilience4j.bulkhead.annotation.Bulkhead;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

@RestController
public class OrderCircuitController {
    @Resource
    private PayFeignApi payFeignApi;

    @GetMapping("/feign/pay/circuit/{id}")
//    @CircuitBreaker的作用是对FeignClient接口的调用进行熔断保护
//    name 表示要保护的服务名称 fallbackMethod表示服务降级后的回调方法
    @CircuitBreaker(name = "cloud-payment-service", fallbackMethod = "myCircuitBreakerFallback")
    public String myCircuitBreaker(@PathVariable("id") Integer id) {
        return payFeignApi.myCircuit(id);
    }

    //myCircuitBreaker就是服务降级后的回调方法处理
    public String myCircuitBreakerFallback(Integer id, Throwable e) {
        return "系统繁忙，稍后再试---myCircuitBreakerFallback: " +
                id + " " + e.getMessage();
    }

    /**
     * (船的)舱壁,隔离
     *
     * @param id
     * @return
     */
//    @GetMapping(value = "/feign/pay/bulkhead/{id}")
//    @Bulkhead(name = "cloud-payment-service", fallbackMethod = "myBulkheadFallback", type = Bulkhead.Type.SEMAPHORE)
//    public String myBulkhead(@PathVariable("id") Integer id) {
//        return payFeignApi.myBulkHead(id);
//    }
//
//    public String myBulkheadFallback(Throwable t) {
//        return "myBulkheadFallback，隔板超出最大数量限制，系统繁忙，请稍后再试-----/(ㄒoㄒ)/~~";
//    }
//

    /**
     * (船的)舱壁,隔离,THREADPOOL
     *
     * @param id
     * @return
     */
    @GetMapping(value = "/feign/pay/bulkhead/{id}")
    @Bulkhead(name = "cloud-payment-service", fallbackMethod = "myBulkheadPoolFallback", type = Bulkhead.Type.THREADPOOL)
    public CompletableFuture<String> myBulkheadTHREADPOOL(@PathVariable("id") Integer id) {
        System.out.println(Thread.currentThread().getName() + "\t" + "enter the method!!!");
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "\t" + "exist the method!!!");
//        CompletableFuture.supplyAsync(new Supplier<String>() {
//            @Override
//            public String get() {
//                return payFeignApi.myBulkHead(id) + "\t" + " Bulkhead.Type.THREADPOOL";
//            }
//        });

        return CompletableFuture.supplyAsync(() -> payFeignApi.myBulkHead(id) + "\t" + " Bulkhead.Type.THREADPOOL");
    }

    public CompletableFuture<String> myBulkheadPoolFallback(Integer id, Throwable t) {
        return CompletableFuture.supplyAsync(() -> "Bulkhead.Type.THREADPOOL，系统繁忙，请稍后再试-----/(ㄒoㄒ)/~~");
    }

    @GetMapping(value = "/feign/pay/ratelimit/{id}")
    @RateLimiter(name = "cloud-payment-service", fallbackMethod = "myRateLimiterFallback")
    public String myRateLimiter(@PathVariable("id") Integer id) {
        return payFeignApi.myRatelimit(id);
    }

    public String myRateLimiterFallback(Integer id, Throwable t) {
        return "系统繁忙，被限流了，稍后再试---myRateLimiterFallback: " +
                id + " " + t.getMessage();
    }


}
